<cfsetting enablecfoutputonly="true">
<cfswitch expression="#thisTag.executionMode#">
	<cfcase value="start">
		<cfparam name="ATTRIBUTES.id">
		<cfparam name="ATTRIBUTES.data" default="">
		<cfparam name="ATTRIBUTES.maxrows" default="0">
		<cfparam name="ATTRIBUTES.link" default="">
		<cfparam name="ATTRIBUTES.linkField" default="">
		<cfparam name="ATTRIBUTES.wrapElement" default="ul">
		<cfparam name="ATTRIBUTES.itemWrapElement" default="li">
		<cfparam name="ATTRIBUTES.displayField" default="display">
		<cfparam name="ATTRIBUTES.pageSize" default="">
		<cfparam name="ATTRIBUTES.pagerLocation" default="bottom"><!--- allowed values include top,bottom, and both  --->
		<cfparam name="ATTRIBUTES.pageNum" default="1">
		<cfparam name="ATTRIBUTES.renderPath" default="">
		<cfparam name="ATTRIBUTES.renderModule" default="">
		<cfparam name="ATTRIBUTES.renderInclude" default="">
		<cfparam name="ATTRIBUTES.runEmpty" default="false">
		<cfparam name="ATTRIBUTES.innerATTRIBUTES" default="#structNew()#">
		<cfparam name="ATTRIBUTES.linkATTRIBUTES" default="#structNew()#">
		<cfparam name="ATTRIBUTES.delimiters" default=",">
		<cfparam name="ATTRIBUTES.listItems" default="">
		<cfparam name="ATTRIBUTES.formatter" type="string" default="">
		<cfparam name="ATTRIBUTES.formatterMask" type="string" default="">
		<cfparam name="ATTRIBUTES.formatterType" type="string" default="">
		<cfparam name="ATTRIBUTES.formatterVersion" type="string" default="">
		<cfif StructKeyExists(caller,'root')>
			<cfset root = caller.root>
		<cfelse>
			<cfset root = caller>
		</cfif>
		<cfif NOT thisTag.hasEndTag>
			<cfthrow detail="End tag required" message="All coop tags require an end tag." errorcode="sos.tag.ATTRIBUTES">
		</cfif>			
		<cfif ATTRIBUTES.id EQ ''>
			<cfthrow detail="Missing required attribute: 'id'" message="'id' attribute is required">
		</cfif>
		<cfif NOT structKeyExists(root,"coop")>
			<cfthrow detail="Missing required COOP object on calling page.">
		</cfif>
		<cfif ATTRIBUTES.pageSize NEQ '' AND ATTRIBUTES.pageNum EQ ''>
			<cfthrow message="The pageNum attribute is required when you pass the page size attribute.">
		</cfif>
		<cfscript>
		if(structKeyExists(root,"coop")){
			coop = root.coop;
		}
		standardATTRIBUTES = 'id,formatter,formatterVersion,formatterMask,formatterType,data,pageSize,pagerLocation,pageNum,displayField,innerATTRIBUTES,ordered,delimiters,link,linkField,innerAttribs,innerAttribValues,renderPath,renderModule,renderInclude,runEmpty,itemWrapElement,wrapElement,listItems';
		ignoredInnerATTRIBUTES = 'id';
		ignoredLinkATTRIBUTES = 'id';
		contentAttributeList = '';
		ATTRIBUTES = root.coop.mergeATTRIBUTES(ATTRIBUTES,root);
		attributeList = root.coop.createAttributeList(ATTRIBUTES,standardATTRIBUTES,root);
		listItemATTRIBUTES = '';
		contentAttributeValueList = '';
		innerDataAttributeList = '';
		innerAttributeList = '';
		linkAttributeList = '';
		linkDataAttributeList = '';
		thisTag.innerATTRIBUTES = arrayNew(1);
		thisTag.linkATTRIBUTES = arrayNew(1);
		thisTag.innerDataATTRIBUTES = structNew();
		thisTag.linkDataATTRIBUTES = structNew();
		pagerString = '';
		renderMode = "default";
		device = root.coop.sosContent.getDevice();
		if (len(device)) {
			device = '_' & device;
			deviceCheck = true;
		} else {
			deviceCheck = false;	
		}
		
		if(len(ATTRIBUTES.renderInclude)){
			renderMode = "include";
			renderSet = reMatchNoCase("^@.[^@]+@",ATTRIBUTES.renderInclude);
			if(arraylen(renderSet) && structKeyExists(root,"_api")){
				renderKey = replace(renderSet[1],"@","","ALL");
				ATTRIBUTES.renderInclude = replace(ATTRIBUTES.renderInclude,renderSet[1],"");
				if(len(ATTRIBUTES.renderInclude)){
					ATTRIBUTES.renderPath = root._api[renderKey].get_includePath();
				}
			}
			if (ATTRIBUTES.renderPath EQ '') {
				ATTRIBUTES.renderPath = root.coop.get_sharePath() & 'tags/coop/includes/';
			}
			if (deviceCheck && fileExists(expandPath(ATTRIBUTES.renderPath & renderInclude & device))) {
				ATTRIBUTES.renderInclude &= device;
			}
			
		} else if(len(ATTRIBUTES.renderModule)){
			renderMode = "module";
			renderSet = reMatchNoCase("^@.[^@]+@",ATTRIBUTES.renderModule);
			if(arraylen(renderSet) && structKeyExists(root,"_api")){
				renderKey = replace(renderSet[1],"@","","ALL");
				ATTRIBUTES.renderModule = replace(ATTRIBUTES.renderModule,renderSet[1],"");
				if(!len(ATTRIBUTES.renderPath)){
					ATTRIBUTES.renderPath = root._api[renderKey].get_modulePath();
				}
			}
			if (ATTRIBUTES.renderPath EQ '') {
				ATTRIBUTES.renderPath = root.coop.get_sharePath() & 'tags/coop/renderers/';
			}
			if (deviceCheck && fileExists(expandPath(ATTRIBUTES.renderPath & ATTRIBUTES.renderModule & device))) {
				ATTRIBUTES.renderModule &= device;
			}
		}
		
		ATTRIBUTES.wrapElement = trim(ATTRIBUTES.wrapElement);
		ATTRIBUTES.itemWrapElement = trim(ATTRIBUTES.itemWrapElement);
		</cfscript><!--- 
		<cfoutput>
		#renderMode#
		<cfdump var="#renderSet#" label="#structKeyExists(root,"_api")#">
		<cfdump var="#root._api#">
		<br>
		#ATTRIBUTES.renderPath#
		<br>
		#ATTRIBUTES.renderInclude#
		</cfoutput>
		<cfabort> --->
	</cfcase>
	<cfcase value="end">
		<cfsavecontent variable="formElement">
			<cfscript>
			if (listLen(structKeyList(ATTRIBUTES.innerATTRIBUTES))) {
				if (NOT arrayLen(thisTag.innerATTRIBUTES)) {
					thisTag.innerATTRIBUTES[1] = structNew();
				}
				structAppend(thisTag.innerATTRIBUTES[1],ATTRIBUTES.innerATTRIBUTES);
			}
			if (listLen(structKeyList(ATTRIBUTES.linkATTRIBUTES))) {
				if (NOT arrayLen(thisTag.linkATTRIBUTES)) {
					thisTag.linkATTRIBUTES[1] = structNew();
				}
				structAppend(thisTag.linkATTRIBUTES[1],ATTRIBUTES.linkATTRIBUTES);
			}
			if (arrayLen(thisTag.innerATTRIBUTES)) {
				for (iAttrib in thisTag.innerATTRIBUTES[1]) {
					if (left(iAttrib,5) EQ 'data_') {
						thisTag.innerDataATTRIBUTES[iAttrib] = thisTag.innerATTRIBUTES[1][iAttrib];
						structDelete(thisTag.innerATTRIBUTES[1],iAttrib);
					}
				}
			}
			if (arrayLen(thisTag.linkATTRIBUTES)) {
				for (iAttrib in thisTag.linkATTRIBUTES[1]) {
					if (left(iAttrib,5) EQ 'data_') {
						thisTag.linkDataATTRIBUTES[iAttrib] = thisTag.linkATTRIBUTES[1][iAttrib];
						structDelete(thisTag.linkATTRIBUTES[1],iAttrib);
					}
				}
			}
			if (arrayLen(thisTag.innerATTRIBUTES)) {
				innerAttributeList = root.coop.createAttributeList(thisTag.innerATTRIBUTES[1],ignoredInnerATTRIBUTES,root);
			}
			if (arrayLen(thisTag.linkATTRIBUTES)) {
				 linkAttributeList = root.coop.createAttributeList(thisTag.linkATTRIBUTES[1],ignoredLinkATTRIBUTES,root);
			}
			if (isSimpleValue(ATTRIBUTES.data) AND ATTRIBUTES.data EQ ''){
				ATTRIBUTES.data = thisTag.generatedContent;
				thisTag.generatedContent = '';
			}
			returnData = createObject("component","#root.coop.get_shareClassPath()#objects.coop.returnData").init(ATTRIBUTES.data,ATTRIBUTES.delimiters);
			start = 1;
			recordCount = returnData.recordCount();
			
			if (ATTRIBUTES.pageSize NEQ '') {
				pagesPossible = recordCount / ATTRIBUTES.pageSize;
				if (listLen(pagesPossible,'.') GT 1) {
					pagesPossible = ceiling(pagesPossible);
				}
				if (ATTRIBUTES.pageSize LTE recordCount) {
					if (ATTRIBUTES.pageNum * ATTRIBUTES.pageSize LTE recordCount) {
						start = ATTRIBUTES.pageNum * ATTRIBUTES.pageSize - ATTRIBUTES.pageSize + 1;
						recordCount = ATTRIBUTES.pageNum * ATTRIBUTES.pageSize;
					} else {
						start = recordCount - (ATTRIBUTES.pageNum * ATTRIBUTES.pageSize - recordCount) + 2;
					}
				}
				if (ATTRIBUTES.pageNum EQ 1) {
					pages = min(pagesPossible,10);
					startPage = 1;
				} else {
					pages = min(pagesPossible,max(ATTRIBUTES.pageNum + 5,10));
					startPage = max(1,ATTRIBUTES.pageNum - 5);
				}
				if (ATTRIBUTES.PageNum NEQ 1) {
					pagerString = pagerString & '<a href="?_#ATTRIBUTES.id#_page=1">&lt;&lt;&nbsp;</a>&nbsp;';
					pagerstring = pagerString & '<a href="?_#ATTRIBUTES.id#_page=#ATTRIBUTES.pageNum -1#">&lt;</a>&nbsp;';
				}
				for (iPage = startPage; iPage LTE pages; iPage = iPage + 1) {
					if (iPage EQ ATTRIBUTES.pageNum) {
						pagerString = pagerString & '<span id="list_#ATTRIBUTES.id#_pager">|&nbsp;#ATTRIBUTES.pageNum#&nbsp;|</span>';
					} else {
						pagerString = pagerString & '<a href="?_#ATTRIBUTES.id#_page=#iPage#">&nbsp;#iPage#&nbsp;</a>';
					}
				}
				if (ATTRIBUTES.pageNum LT pagesPossible) {
					pagerString = pagerString & '<a href="?_#ATTRIBUTES.id#_page=#ATTRIBUTES.pageNum + 1#">&nbsp;&gt;</a>';
					pagerString = pagerString & '<a href="?_#ATTRIBUTES.id#_page=#pagesPossible#">&nbsp;&gt;&gt;</a>';
				}
			}
			writeOutput('<#ATTRIBUTES.wrapElement# id="#ATTRIBUTES.id#"#attributeList#>');
			for(iRow=start; iRow LTE recordCount; iRow = iRow + 1) {
				data = returnData.returnDataRowStruct(iRow);
				data.__meta__ = {
					start = iif(iRow==1,"true","false"),
					end = iif(iRow==recordCount,"true","false"),
					listItems = ATTRIBUTES.listItems,
					item = iRow,
					maxrows = ATTRIBUTES.maxrows,
					recordCount = recordCount
				};
				data.__ATTRIBUTES = ATTRIBUTES;
				if(returnData.is_ORMData()){
					data.__entity = returnData.returnORMRow(iRow);
				}
				writeOutput(_getItemContent(data:data));
			}
			writeOutput('</#ATTRIBUTES.wrapElement#>');
			
			</cfscript>
			<cfif ATTRIBUTES.runEmpty AND recordCount EQ 0>
	        	<cfscript>
				data = {
					display = "",
					value = "",
					__meta__ = {
						start = true,
						end = true,
						listItems = ATTRIBUTES.listItems,
						item = 0,
						maxrows = ATTRIBUTES.maxrows,
						recordCount = recordCount
					},
					__ATTRIBUTES = ATTRIBUTES
				};
				</cfscript>
	        	<cfoutput>#_getItemContent(data:VARIABLES.data)#</cfoutput>
        	</cfif>
			</cfsavecontent>
			<cfif ATTRIBUTES.pagerLocation EQ 'top'>
				<cfset formElement = pagerString & formElement>
			<cfelseif ATTRIBUTES.pagerLocation EQ 'bottom'>
				<cfset formElement = formElement & pagerString>
			<cfelseif ATTRIBUTES.pagerLocation EQ 'both'>
				<cfset formElement = pagerString & formElement & pagerString>
			</cfif>
			<cfoutput>#formElement#</cfoutput>
			<cfset thisTag.generatedContent = "">
		</cfcase>
</cfswitch>
<cffunction name="_getItemContent">
	<cfargument name="data" />
	
	<cfset var itemContent = ''>
	<cfset var content = ''>
	<cfset var contentAttributeValuesList = ''>
	<cfsavecontent variable="itemContent">
		<cfswitch expression="#renderMode#">
			<cfcase value="module">
				<cfmodule template="#ATTRIBUTES.renderPath##ATTRIBUTES.renderModule#.cfm" attributeCollection="#arguments#">
			</cfcase>
			<cfcase value="include">
				<cfinclude template="#ATTRIBUTES.renderPath#_#ATTRIBUTES.renderInclude#.cfm">
			</cfcase>
			<cfdefaultCase>
				<cfscript>
				if (ATTRIBUTES.displayField EQ '')  {
					content = data[1];
				} else {
					if (reFindNoCase("##*##",ATTRIBUTES.displayField)) {
						content = evaluate(ATTRIBUTES.displayField);
					} else {
						content = data[ATTRIBUTES.displayField];
					}
				}
				if (len(ATTRIBUTES.formatter)) {
					content = root.coop._formatter(ATTRIBUTES.formatter,itemContent,ATTRIBUTES);
				}
				innerDataAttributeList = '';
					for (iAttrib in thisTag.innerDataATTRIBUTES) {
						if (reFindNoCase("##*##",thisTag.innerDataATTRIBUTES[iAttrib])) {
							innerDataAttributeList = listAppend(innerDataAttributeList,'#right(iAttrib,len(iAttrib)-5)#="#evaluate(thisTag.innerDataATTRIBUTES[iAttrib])#"'," ");
						} else {
							innerDataAttributeList = listAppend(innerDataAttributeList,'#right(iAttrib,len(iAttrib)-5)#="#data[thisTag.innerDataATTRIBUTES[iAttrib]]#"'," ");
						}
					}
					linkDataAttributeList = '';
					for (iAttrib in thisTag.linkDataATTRIBUTES) {
						if (reFindNoCase("##*##",thisTag.linkDataATTRIBUTES[iAttrib])) {
							linkDataAttributeList = listAppend(linkDataAttributeList,'#right(iAttrib,len(iAttrib)-5)#="#evaluate(thisTag.linkDataATTRIBUTES[iAttrib])#"'," ");
						} else {
							linkDataAttributeList = listAppend(linkDataAttributeList,'#right(iAttrib,len(iAttrib)-5)#="#data[thisTag.linkDataATTRIBUTES[iAttrib]]#"'," ");
						}
					}
					if (innerDataAttributeList NEQ ''){
						innerDataAttributeList = ' ' & innerDataAttributeList;
					}
					if (linkDataAttributeList NEQ ''){
						linkDataAttributeList = ' ' & linkDataAttributeList;
					}
					writeOutput('<#ATTRIBUTES.itemWrapElement##innerAttributeList##innerDataAttributeList#>');
					if (ATTRIBUTES.link NEQ '') {
						link = '';
						if (ATTRIBUTES.linkField NEQ '') {
							if (reFindNoCase("##*##",ATTRIBUTES.linkField)) {
								link = evaluate(ATTRIBUTES.linkField);
							} else {
								link = data[ATTRIBUTES.linkField];
							}
						}
						writeOutput('<a href="#ATTRIBUTES.link##link#"#linkAttributeList##linkDataAttributeList#>#content#</a>');
					}
					else if (ATTRIBUTES.link EQ '' AND ATTRIBUTES.linkField NEQ ''){
						if (ATTRIBUTES.linkField NEQ '') {
							if (reFindNoCase("##*##",ATTRIBUTES.linkField)) {
								link = evaluate(ATTRIBUTES.linkField);
							} else {
								link = data[ATTRIBUTES.linkField];
							}
						}
						writeOutput('<a href="#ATTRIBUTES.link##link#"#linkAttributeList##linkDataAttributeList#>#content#</a>');
					} else {
						writeOutput(content);
					}
						writeOutput('</#ATTRIBUTES.itemWrapElement#>');
				</cfscript>
			</cfdefaultCase>
		</cfswitch>
	</cfsavecontent>
	
	<cfreturn itemContent>
</cffunction>

<cfsetting enablecfoutputonly="false">